package com.demo.stream_.collect;

import com.demo.stream_.Person;
import lombok.Builder;
import lombok.Data;
import org.junit.Test;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author gy
 * @date 2022/5/11
 * 分区：将stream按条件分为两个 Map，比如员工按照薪资是否高于800分为两个部分
 * 分组：将结合分为多个Map，比如员工按照性别分组。有单极分组和多级分组
 */
public class PartitioningByGroupingBy {
    /**
     * 将员工按薪资是否高于8000分为两部分；
     * 将员工按性别和地区分组
     */
    @Test
    public void m1(){
        List<Person> personList = new ArrayList<Person>();
        personList.add(new Person("Tom", 8900, "male", "New York"));
        personList.add(new Person("Jack", 7000, "male", "Washington"));
        personList.add(new Person("Lily", 7800, "female", "Washington"));
        personList.add(new Person("Anni", 8200, "female", "New York"));
        personList.add(new Person("Owen", 9500, "male", "New York"));
        personList.add(new Person("Alisa", 7900, "female", "New York"));

        // 将员工按薪资是否高于8000分组
        Map<Boolean, List<Person>> part = personList.stream().collect(Collectors.partitioningBy(x -> x.getSalary() > 8000));
        // 将员工按性别分组
        Map<String, List<Person>> group = personList.stream().collect(Collectors.groupingBy(Person::getSex));

        // 将员工按照性别分组后 再按照区域分组
        Map<String, Map<String, List<Person>>> sexMap =
                personList.stream().collect(Collectors.groupingBy(Person::getSex,
                        Collectors.groupingBy(Person::getArea)));

        HashMap<String, String> result = new HashMap<>();

        /**
         * 20220512
         * 需求：将相同名字的，人名 拼串
         * 测试结果{female=Lily,Anni,Alisa, male=Tom,Jack,Owen}
         */
        // 开始遍历 map
        Iterator<Map.Entry<String, List<Person>>> entries = group.entrySet().iterator();
        while (entries .hasNext()){
            Map.Entry<String, List<Person>> entry = entries.next();
            String sex = entry.getKey();
            List<Person> people = entry.getValue();
            String names = people.stream()
                    .map(p -> p.getName()).
                    collect(Collectors.joining(","));
            result.put(sex,names);
        }
        System.out.println("测试结果" + result);

        // 将员工先按性别分组，再按地区分组
        Map<String, Map<String, List<Person>>> group2 = personList.stream().
                collect(Collectors.groupingBy(Person::getSex, Collectors.groupingBy(Person::getArea)));
        System.out.println("员工按薪资是否大于8000分组情况：" + part);
        System.out.println("员工按性别分组情况：" + group);
        System.out.println("员工按性别、地区：" + group2);

    }


    @Test
    public void m2(){
        List<TestData> list = new ArrayList<>();
        TestData.TestDataBuilder builder = TestData.builder();
        builder.id(1).name("老王").age(50).address("隔壁");
        list.add(builder.build());
        builder.id(2).name("司马老贼").age(45).address("许昌");
        list.add(builder.build());
        builder.id(3).name("曹贼").age(43).address("许昌");
        list.add(builder.build());
        builder.id(4).name("大耳朵").age(52).address("益州");
        list.add(builder.build());
        builder.id(5).name("燕人").age(58).address("益州");
        list.add(builder.build());

        System.out.println(list);

//        Map<String, TestData> map = list.stream().collect(
//                Collectors.groupingBy(TestData::getAddress, Collectors.collectingAndThen(
//                        Collectors.reducing((t1, t2) -> t1.getAge() > t2.getAge() ? t1 : t2),
//                        Optional::get
//                ))
//        );

        Map<String, Integer> map = list.stream().collect(
                Collectors.groupingBy(TestData::getAddress, Collectors.summingInt(TestData::getAge))
        );

        System.out.println(map);
    }
}

@Data
@Builder
class TestData{
    private Integer id;
    private String name;
    private Integer age;
    private String address;
}